package middleware

import (
	"bytes"
	"context"
	"fmt"
	"hrt/internal/common"
	"io"
	"net/http"
	"sort"
)

type TransparentRequestMiddleware struct {
}

func NewTransparentRequestMiddleware() *TransparentRequestMiddleware {
	return &TransparentRequestMiddleware{}
}

func (m *TransparentRequestMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		httpRequest := common.HttpRequest{}
		httpRequest.Proto = r.Proto
		httpRequest.Method = r.Method
		httpRequest.URL = r.URL
		httpRequest.Header = r.Header
		httpRequest.ContentLength = r.ContentLength
		httpRequest.TransferEncoding = r.TransferEncoding
		httpRequest.Host = r.Host
		body, _ := io.ReadAll(r.Body)
		r.Body = io.NopCloser(bytes.NewBuffer(body)) // 创建 io.ReadCloser 对象传给 request body
		httpRequest.Body = string(body)
		r.ParseForm()
		httpRequest.Form = r.Form
		httpRequest.PostForm = r.PostForm
		httpRequest.PostForm = r.PostForm
		httpRequest.RemoteAddr = r.RemoteAddr
		httpRequest.RequestURI = r.RequestURI
		httpRequest.UserAgent = r.UserAgent()
		httpRequest.Referer = r.Referer()
		httpRequest.Cookie = r.Cookies()
		authInfo, err := r.Cookie("Authorization")
		if err == nil {
			httpRequest.Authorization = authInfo.Value
		}

		httpRequest.AllMessage = fmt.Sprintf("%s %s %s\r\n", httpRequest.Method, httpRequest.URL, httpRequest.Proto)
		if httpRequest.Header != nil {
			var headers []string
			for k, v := range httpRequest.Header {
				headers = append(headers, fmt.Sprintf("%s:%s\r\n", k, v))
			}
			sort.Strings(headers)
			for _, item := range headers {
				httpRequest.AllMessage += item
			}
		}
		// 获取真实ip
		httpRequest.RealIp = r.Header.Get("X-Forwarded-For")
		if httpRequest.RealIp == "" {
			httpRequest.RealIp = r.Header.Get("WL-Proxy-Client-IP")
		}
		if httpRequest.RealIp == "" {
			httpRequest.RealIp = r.Header.Get("HTTP_CLIENT_IP")
		}
		if httpRequest.RealIp == "" {
			httpRequest.RealIp = r.Header.Get("X-Real-IP")
		}
		if httpRequest.RealIp == "" {
			httpRequest.RealIp = r.RemoteAddr
		}
		httpRequest.AllMessage += fmt.Sprintf("\r\n%s", httpRequest.Body)
		ctx := context.WithValue(r.Context(), common.HttpRequestKey, httpRequest)
		next.ServeHTTP(w, r.WithContext(ctx))
	}
}
